package com.leyou.cart.service;

import com.leyou.auth.pojo.UserInfo;
import com.leyou.cart.client.GoodsClient;
import com.leyou.cart.mapper.CollectMapper;
import com.leyou.cart.pojo.Cart;
import com.leyou.cart.pojo.Collect;
import com.leyou.common.utils.JsonUtils;
import com.leyou.cart.interceptor.LoginInterceptor;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.Spu;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class CartService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private CollectMapper collectMapper;

    // 设置放入Redis中Map<key,Map<k,v>>中的key，以获取指定用户的购物车
    private static final String LEYOU_CART_PREFIX = "leyou:cart:";

    /**
     * 添加购物车到Redis业务
     * @param cart
     */
    public void addCartsToRedis(Cart cart) {

        // 获取用户信息
        UserInfo userInfo = LoginInterceptor.getUserInfoFromThread();

        // 先查询之前的购物车数据
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(LEYOU_CART_PREFIX+userInfo.getId());

        Boolean existSku = boundHashOps.hasKey(cart.getSkuId().toString());

        // 记录传递过来的cart参数中的数量
        Integer num = cart.getNum();

        if (existSku){
            // 该用户的购物车中已存在该商品，只有更新数量即可
            // 获取Redis中对应购物车的json字符串对象
            String cartJson = boundHashOps.get(cart.getSkuId().toString()).toString();
            // 将json格式的字符串反序列化为cart对象
            cart = JsonUtils.parse(cartJson, Cart.class);
            // 更新数量
            cart.setNum(cart.getNum()+num);
        }else{
            // 该用户的购物车中不存在该商品
            cart.setUserId(userInfo.getId());
            // 根据cart中的skuId查询对应的sku
            Sku sku = goodsClient.querySkuById(cart.getSkuId());
            // 给购物车cart对象赋值
            cart.setImage(StringUtils.isBlank(sku.getImages()) ? "" : StringUtils.split(sku.getImages(),",")[0]);

            cart.setOwnSpec(sku.getOwnSpec());
            cart.setPrice(sku.getPrice());
            cart.setTitle(sku.getTitle());

        }

        // 保存购物车cart信息到Redis中
        boundHashOps.put(cart.getSkuId().toString(),JsonUtils.serialize(cart));

    }

    // 查询当前用户的购物车信息
    public List<Cart> queryCartsOfCurrentUser() {
        // 获取当前用户信息
        UserInfo userInfo = LoginInterceptor.getUserInfoFromThread();
        // 查询该用户(uid)的购物车信息
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(LEYOU_CART_PREFIX + userInfo.getId());
        // 获取Redis中value值
        List<Object> cas = boundHashOps.values();
        // 判断购物车集合是否为空
        if (CollectionUtils.isEmpty(cas)){
            return null;
        }

        List<Cart> carts = cas.stream().map(c -> JsonUtils.parse(c.toString(), Cart.class)).collect(Collectors.toList());


        // 查询mysql中的cart--skuId对应的sku
        // 获取carts集合中所有的skuId
        List<Long> skuIds = carts.stream().map(Cart::getSkuId).collect(Collectors.toList());
        // 根据skuId集合查询对应的skus集合
        List<Sku> skus = goodsClient.queySkusByIds(skuIds);

        // 查询skus中的spuId
        List<Long> spuIds = skus.stream().map(Sku::getSpuId).distinct().collect(Collectors.toList());

        // 根据spuId查询对应的spus
        List<Spu> spus = goodsClient.querySpusBySpuIds(spuIds);

        for (int i = 0; i < carts.size(); i++) {
            for (int j = 0; j < skus.size(); j++) {
                if (skus.get(j).getId().equals(carts.get(i).getSkuId())){
                    // 赋值最新价格
                    carts.get(i).setRealPrice(skus.get(j).getPrice());
                    Long spuId = skus.get(j).getSpuId();

                    // 查找对应的spu
                    Object[] objects = spus.stream().filter(spu -> spu.getId().equals(spuId)).toArray();

                    // 赋值上下架参数
                    carts.get(i).setSaleable(((Spu)(objects[0])).getSaleable());
                    break;
                }
            }
        }

        return carts;


    }

    // 修改购物车商品数量同时修改Redis中对应的数据
    public void updateCartNumOfCurrentUser(Long skuId, Integer num) {
        // 获取当前用户信息
        UserInfo userInfo = LoginInterceptor.getUserInfoFromThread();
        // 查询该用户的购物车信息
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(LEYOU_CART_PREFIX + userInfo.getId());
        // 获取参数skuId对应的cart对象
        String cartJson = boundHashOps.get(skuId.toString()).toString();
        // 反序列化
        Cart cart = JsonUtils.parse(cartJson, Cart.class);
        // 更改cart购物车对象中的数量
        cart.setNum(num);
        // 将修改后的cart对象再保存至Redis中
        boundHashOps.put(skuId.toString(),JsonUtils.serialize(cart));
    }

    // 用户登录后删除购物车业务
    public void deleteCartOfCurrentUser(Long skuId) {
        // 获取当前用户信息
        UserInfo userInfo = LoginInterceptor.getUserInfoFromThread();
        // 获取该用户的购物车信息
        BoundHashOperations<String, Object, Object> boundHashOps = redisTemplate.boundHashOps(LEYOU_CART_PREFIX + userInfo.getId());
        // 删除其中对应的skuId购物车信息
        boundHashOps.delete(skuId.toString());
    }

    // 用户登录后将localstorage内的购物车数据添加至Redis中，并查询Redis和mysql中cart对象相关数据
    public List<Cart> addLocalStorageCartsToRedisAndQuery(List<Cart> localCarts) {
        // 将localstorage内的购物车数据添加至Redis中
        localCarts.forEach(cart -> this.addCartsToRedis(cart));
        // 查询Redis中数据
        List<Cart> carts = this.queryCartsOfCurrentUser();

        // 返回购物车集合
        return carts;
    }

    // 根据skuIds集合查询对应skus集合
    public List<Sku> querySkusByids(List<Long> ids) {
        return goodsClient.queySkusByIds(ids);
    }

    // 用户点击关注，将购物车移动到我的收藏
    public void transferCartToCollect(Long skuId) {
        // 获取当前用户信息
        UserInfo userInfo = LoginInterceptor.getUserInfoFromThread();
        // 先查询该用户是否收藏过该商品
        Collect collect = new Collect();
        collect.setSkuId(skuId);
        collect.setUserId(userInfo.getId());
        int count = collectMapper.selectCount(collect);
        if (count == 0){
            // 用户没有收藏该商品

            collect.setId(null);

            // 根据skuid查询sku
            Sku sku = goodsClient.querySkuById(skuId);
            collect.setImage(StringUtils.isBlank(sku.getImages()) ? "" : StringUtils.split(sku.getImages(),",")[0]);
            collect.setOwnSpec(sku.getOwnSpec());
            collect.setPrice(sku.getPrice());
            collect.setTitle(sku.getTitle());

            // 添加数据到数据库
            collectMapper.insert(collect);
        }
    }
}
